using System;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Reflection;

using FridayShopping.DataModel;
using FridayShopping.Util;

namespace FridayShopping.UI
{
	public class ShoppingListFormManager : ProducstListFormManager
	{
		private	int completedCount;

		private bool hidePurchased;

		private float totalPrice;

		private float completePrice;

		private Shop  shop;

		private Categories categories;

		public event EventHandler ShopListChanged;

		#region Constructor
		public ShoppingListFormManager(IListViewForm form, ListView listView, Categories categories, Shop shop) : 
			base (form, listView, categories)
		{
			CurrentCategoryKey = new Key(-1);
			completedCount = 0;
			list = categories.ProductsByCategory;
			this.shop = shop;
			this.categories = categories;

			// Calculate total list price
			totalPrice = 0;
			foreach (Product product in list.List)
			{
				totalPrice+= (product.Price * (product.Amount - product.Purchased));
			}
		}

		#endregion

		#region Member Access
		public int CompletedCount
		{
			get
			{
				return completedCount;
			}
			set 
			{
				completedCount = value;
			}
		}

		public bool HidePurchased
		{
			get 
			{
				return hidePurchased;
			}
			set
			{
				hidePurchased = value;
			}
		}

		public float TotalPrice
		{
			get
			{
				return totalPrice;
			}
		}

		public float CompletePrice
		{
			get
			{
				return completePrice;
			}
			set 
			{
				completePrice = value;
			}
		}

		#endregion

		public void HandleItemActivateEvent() 
		{
			Key key = GetItemKey(listView.FocusedItem);
			Product item = (Product)list.GetItem(key);
			if (item == null)
			{
				return;
			}
			if (!item.PurchaseComplete) 
			{
				int before = item.Purchased;
				item.TakeAll();
				CompletePrice+=((item.Purchased - before) * item.Price);
				CompletedCount++;
				RefreshCurrentItem(item);
				FireShopListEvent();
			}
		}

		public override void ToolbarEventsHandler(ToolBarButtonClickEventArgs e)
		{
			if (e.Button == ((ShopListForm)form).toolBarButton_Plus) 
			{
				Key key = GetItemKey(listView.FocusedItem);
				Product item = (Product)list.GetItem(key);
				if (item == null)
				{
					return;
				}
				if (!item.PurchaseComplete) 
				{
					item.TakeOne();
					CompletePrice+=item.Price;
					if (item.PurchaseComplete) 
					{
						CompletedCount++;
					}
					FireShopListEvent();
					RefreshCurrentItem(item);
				}
			}
			if (e.Button == ((ShopListForm)form).toolBarButton_Minus) 
			{
				Key key = GetItemKey(listView.FocusedItem);
				Product item = (Product)list.GetItem(key);
				if (item == null)
				{
					return;
				}
				if (item.Purchased > 0) 
				{
					item.ReturnOne();
					CompletePrice-=item.Price;
					if (item.Amount - item.Purchased == 1) 
					{
						if (CompletedCount > 0) 
						{
							CompletedCount--;
						}
					}
				}
				FireShopListEvent();
				RefreshCurrentItem(item);
			}
			if (e.Button == ((ShopListForm)form).toolBarButton_Notes)
			{
				Key key = GetItemKey(listView.FocusedItem);
				Product item = (Product)list.GetItem(key);
				if (item == null)
				{
					return;
				}
				MessageBox.Show(item.Memo, LangResources.Instance.Resources.GetString("applName"));
			}
			if (e.Button == ((ShopListForm)form).toolBarButton_Delete)
			{
				Key key = GetItemKey(listView.FocusedItem);
				Product item = (Product)list.GetItem(key);
				if (item == null)
				{
					return;
				}			
				if (MessageBox.Show(LangResources.Instance.Resources.GetString("removeFromListConfirm"),
					LangResources.Instance.Resources.GetString("applName"),
					MessageBoxButtons.YesNo,
					MessageBoxIcon.Question,
					MessageBoxDefaultButton.Button2) == DialogResult.Yes) 
				{

					if (CompletedCount > 0) 
					{
						if (item.PurchaseComplete) 
						{
							CompletedCount--;
						}
						CompletePrice-=item.Price;
					}
					item.Amount = 0;
					DeleteItem(listView.FocusedItem);                    
					EnableDisableItems();
					FireShopListEvent();
				}
			}
			if (e.Button == ((ShopListForm)form).toolBarButton_Export)
			{
				string fileName = Database.Instance.ShopListFile;
				ExportList(fileName);

				MessageBox.Show(LangResources.Instance.Resources.GetString("shopListCreated") + fileName,
					LangResources.Instance.Resources.GetString("applName"),
					MessageBoxButtons.OK,
					MessageBoxIcon.Asterisk,
					MessageBoxDefaultButton.Button1);

			}
		}

		protected override bool ShouldAddToListView(ItemBase item)
		{
			if (!HidePurchased) 
			{
				return true;
			}
			Product product = (Product)item;
			return (!product.PurchaseComplete);
		}

		override protected void RefreshIndexedItem(int index, ItemBase item)
		{
			if (HidePurchased && ((Product)item).PurchaseComplete) 
			{
				listView.Items.RemoveAt(index);
				if (listView.Items.Count > 0) 
				{
					if (index >= listView.Items.Count) 
					{
						index = listView.Items.Count - 1;
					}
					listView.Items[index].Focused = true;
					listView.Items[index].Selected = true;
				}
			}
			else
			{
				base.RefreshIndexedItem (index, item);
			}
		}

		protected override ListViewItem CreateListViewItem(ItemBase item)
		{
			Product i = (Product)item;
			string[] subitems = {
									i.Key.ToString(),
									i.Name,
									i.Amount.ToString(),
									i.Purchased.ToString()
			};
			return new ListViewItem(subitems);
		}


		public override void EnableDisableItems()
		{
			bool notEmpty = listView.SelectedIndices.Count > 0;
			ShopListForm shopForm = (ShopListForm)form;
			shopForm.toolBarButton_Minus.Enabled = notEmpty;
			shopForm.toolBarButton_Plus.Enabled = notEmpty;
			shopForm.toolBarButton_Delete.Enabled = notEmpty;

			bool toEnableNotes = false;

			if (notEmpty)
			{
				Key key = GetItemKey(listView.FocusedItem);
				Product item = (Product)list.GetItem(key);
				if (item != null)
				{
					toEnableNotes = (item.Memo.Trim().Length > 0);
				}
			}
			shopForm.toolBarButton_Notes.Enabled = toEnableNotes;
		}

		private void FireShopListEvent() 
		{
			if (ShopListChanged != null)
			{
				ShopListChanged(this,new EventArgs());
			}
		}

		// Canceling shopping. Return all the purchased products.
		public void ReturnAll()
		{
			foreach(Product product in list.List) 
			{
				product.ReturnAll();
			}
		}

		public void ExportList(string fileName)
		{
			// Read from registry PPC name and owner
			bool bHasOwner = false;
			string owner = null;			
			byte[] ownerBuffer = Registry.GetValue(Registry.RootKey.CurrentUser,@"ControlPanel\Owner","Owner");
			if (ownerBuffer != null)
			{
				string ownerString = UnicodeEncoding.Unicode.GetString(ownerBuffer,0, ownerBuffer.Length);
				int eosPos = ownerString.IndexOf('\0');
				owner = ownerString.Substring(0, eosPos);
				if (owner.Length > 0) 
				{
					bHasOwner = true;
				}
			}
			
			Encoding encoding = System.Text.Encoding.ASCII;

			if (string.Compare(Global.Settings.GetString(SettingKeys.PrintFileEncoding),"ascii", true) == 0)
			{
				encoding = System.Text.Encoding.ASCII;
			} 
			else if (string.Compare(Global.Settings.GetString(SettingKeys.PrintFileEncoding),"unicode", true) ==0)
			{
				encoding = System.Text.Encoding.Unicode;
			} 
			else if (string.Compare(Global.Settings.GetString(SettingKeys.PrintFileEncoding),"utf8", true) ==0)
			{
				encoding = System.Text.Encoding.UTF8;
			}

			StreamWriter writer = new StreamWriter(fileName, false, encoding);

			writer.WriteLine("HEADER:" + shop.Name);
			writer.WriteLine("HEADER:" + DateTime.Now.Date.ToLongDateString());
			if (bHasOwner)
			{
				writer.WriteLine("HEADER:" + owner);
			} 
			else 
			{
				string ppcName = Registry.GetString(Registry.RootKey.LocalMachine,@"Ident","Name");
				writer.WriteLine("HEADER:" + ppcName);
			}
			foreach (Category category in categories.List)
			{
				writer.WriteLine("CATEGORY:"+category.Name);
				foreach (Product product in category.Products.List)
				{
					if (product.Amount > 0) 
					{
						writer.WriteLine("PRODUCT:"+product.Amount + "x " + product.Name);
					}
					else
					{
						writer.WriteLine("PRODUCT:"+product.Name);
					}
				}
			}
			writer.WriteLine("APPNAME:"+FridayShopping.Util.Global.AppName + " " +FridayShopping.Util.Global.Version);
			writer.WriteLine("END");
			writer.Close();
		}

		// If at least one item is purchased, the list is not
		// empty
		public bool EmptyList
		{
			get
			{
				foreach(Product product in list.List) 
				{
					if (product.Purchased > 0)
					{
						return false;
					}
				}
				return true;
			}
		}

		// Left the checkout. Subtract the purchased products from the asked
		// products and reset the purchased column.
		public void UpdateAmounts()
		{
			foreach(Product product in list.List) 
			{
				product.UpdateAmounts();
			}
		}

		protected override bool NeedToSort
		{
			get
			{
				return false;
			}
		}
	}
}
